package character.ai;

import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import java.util.ArrayList;
import java.util.List;

/** Holds a list of AIControls which know about each other. */
public class AISpace {
    protected List<AIControl> aiControls;

    public AISpace() {
	aiControls = new ArrayList<AIControl>();
    }

    /**
     * Adds an object to the AI space.
     * @param obj the AIControl or Spatial with AIControl to add
     */
    public void add(Object obj) {
	if (obj instanceof AIControl) {
            ((AIControl)obj).setAISpace(this);
	    aiControls.add((AIControl)obj);
        } else if (obj instanceof Spatial) {
            Spatial spatial = (Spatial)obj;
            AIControl control = spatial.getControl(AIControl.class);
            control.setAISpace(this);
	    aiControls.add(control);
        } else {
            throw (new UnsupportedOperationException("Cannot add this kind of object to the ai space."));
        }
    }

    /**
     * Removes an object from the AI space.
     * @param obj the AIControl or Spatial with AIControl to remove
     */
    public void remove(Object obj) {
	if (obj instanceof AIControl) {
            ((AIControl)obj).setAISpace(null);
	    aiControls.remove((AIControl)obj);
        } else if (obj instanceof Spatial) {
            AIControl control = ((Spatial)obj).getControl(AIControl.class);
            control.setAISpace(null);
	    aiControls.remove(control);
        } else {
            throw (new UnsupportedOperationException("Cannot remove this kind of object from the ai space."));
        }
    }
    
    /**
     * Adds all AI controls in the given Spatial to the AI space
     * (e.g. after loading from disk) - recursive if Node.
     * @param spatial the Spatial or root Node containing the AI objects
     */
    public void addAll(Spatial spatial) {
        if (spatial.getControl(AIControl.class) != null) {
            AIControl aiControl = spatial.getControl(AIControl.class);
            if (!aiControls.contains(aiControl)) {
                aiControl.setAISpace(this);
            }
        }
        //recursion
        if (spatial instanceof Node) {
            for (Spatial child : ((Node)spatial).getChildren()) {
                addAll(child);
            }
        }
    }
    
    /**
     * Removes all AI controls in the given spatial from the AI space
     * (e.g. before saving to disk) - recursive if Node.
     * @param spatial the Spatial or root Node containing the AI objects
     */
    public void removeAll(Spatial spatial) {
        if (spatial.getControl(AIControl.class) != null) {
            AIControl aiControl = spatial.getControl(AIControl.class);
            if (aiControls.contains(aiControl)) {
                aiControl.setAISpace(null);
            }
        }
        //recursion
        if (spatial instanceof Node) {
            for (Spatial spat : ((Node)spatial).getChildren()) {
                removeAll(spat);
            }
        }
    }
}
